package org.pan.domain.db;

import org.pan.domain.DomainObject;
import org.pan.domain.enums.CardUserStateEnum;
import org.pan.domain.enums.EventTypeEnum;

import javax.persistence.*;
import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 * 用户信息
 *
 * Created by panmingzhi on 2015/12/24.
 */
@Entity
public class CardUser extends DomainObject {

    public enum Property{
        identifier,name,birthday,sex,email,IDCard,mobilePhone,fixedPhone,address,groups,cards,lastEventTypeEnum,createTime,cardUserState,userStateRecords,cardUserHeaderImage,cardIdentifierJoinStr,cardSerialNumberJoinStr
    }

    @Column(name = "identifier", unique = true, nullable = false)
    private String identifier;

    // 卡片用户名称
    @Column(name = "name", nullable = false)
    private String name;

    // 卡片用户出生日期
    @Column(name = "birthday")
    @Temporal(value = TemporalType.DATE)
    private Date birthday;

    // 卡片用户性别
    @Column(name = "sex")
    private String sex;

    @Column(name = "email")
    private String email;

    // 卡片用户身份证号
    @Column(name = "IDCard")
    private String IDCard;

    // 卡片用户移动电话
    @Column(name = "tel")
    private String mobilePhone;

    // 卡片用户固话
    @Column(name = "fixedPhone")
    private String fixedPhone;

    // 卡片用户地址
    @Column(name = "address")
    private String address;

    // 此卡片用户所属的用户组
    @ManyToMany
    @JoinTable(name = "User2Group", joinColumns = { @JoinColumn(name = "CardUserID") }, inverseJoinColumns = { @JoinColumn(name = "CardUserGroupID") })
    private List<CardUserGroup> groups = new ArrayList<>();

    // 用户所拥有的卡片
    @OneToMany(mappedBy = "cardUser")
    private List<PhysicalCard> cards = new ArrayList<>();

    @Column(name = "cardIDJoinStr")
    private String cardIdentifierJoinStr;

    @Column(name = "cardSNJoinStr")
    private String cardSerialNumberJoinStr;

    //最后一次刷卡类型
    @Column(name = "lastEventTypeEnum")
    @Enumerated(EnumType.STRING)
    private EventTypeEnum lastEventTypeEnum = EventTypeEnum.InternalReaderNormalSwipe;

    // 建档时间
    @Column(name = "createTime")
    @Temporal(TemporalType.TIMESTAMP)
    private Date createTime;

    //当前用户状态
    @Column
    @Enumerated(EnumType.STRING)
    private CardUserStateEnum cardUserState;

    // 用户历史状态列表,利用级联来删除状态。
    @OneToMany(mappedBy = "cardUser", cascade = CascadeType.REMOVE)
    private List<CardUserStateRecord> userStateRecords = new ArrayList<>();

    //用户头像，使用独立的数据对象存储
    @ManyToOne(fetch = FetchType.LAZY,cascade = CascadeType.REMOVE)
    @JoinColumn(name = "cardUserHeaderImage_id",referencedColumnName = "id",insertable = false,updatable = false)
    private CardUserHeaderImage cardUserHeaderImage;

    @Transient
    private PhysicalCard physicalCard;

    @PrePersist
    @PreUpdate
    public void prePersist(){
        this.createTime = new Date();

        String cardIdentifierJoinStr = cards.stream().map(PhysicalCard::getIdentifier).collect(Collectors.joining(","));
        String cardSerialNumberJoinStr = cards.stream().map(PhysicalCard::getSerialNumber).collect(Collectors.joining(","));
        setCardIdentifierJoinStr(cardIdentifierJoinStr);
        setCardSerialNumberJoinStr(cardSerialNumberJoinStr);
    }

    public static void main(String[] args) {
        List<String> strings = Arrays.asList("123", "234");
        String collect = strings.stream().collect(Collectors.joining(","));
        System.out.println(collect);
    }

    public String getIdentifier() {
        return identifier;
    }

    public void setIdentifier(String identifier) {
        this.identifier = identifier;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getIDCard() {
        return IDCard;
    }

    public void setIDCard(String IDCard) {
        this.IDCard = IDCard;
    }

    public String getMobilePhone() {
        return mobilePhone;
    }

    public void setMobilePhone(String mobilePhone) {
        this.mobilePhone = mobilePhone;
    }

    public String getFixedPhone() {
        return fixedPhone;
    }

    public void setFixedPhone(String fixedPhone) {
        this.fixedPhone = fixedPhone;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public List<CardUserGroup> getGroups() {
        return groups;
    }

    public void setGroups(List<CardUserGroup> groups) {
        this.groups = groups;
    }

    public List<PhysicalCard> getCards() {
        return cards;
    }

    public void setCards(List<PhysicalCard> cards) {
        this.cards = cards;
    }

    public EventTypeEnum getLastEventTypeEnum() {
        return lastEventTypeEnum;
    }

    public void setLastEventTypeEnum(EventTypeEnum lastEventTypeEnum) {
        this.lastEventTypeEnum = lastEventTypeEnum;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public CardUserStateEnum getCardUserState() {
        return cardUserState;
    }

    public void setCardUserState(CardUserStateEnum cardUserState) {
        this.cardUserState = cardUserState;
    }

    public List<CardUserStateRecord> getUserStateRecords() {
        return userStateRecords;
    }

    public void setUserStateRecords(List<CardUserStateRecord> userStateRecords) {
        this.userStateRecords = userStateRecords;
    }

    public CardUserHeaderImage getCardUserHeaderImage() {
        return cardUserHeaderImage;
    }

    public void setCardUserHeaderImage(CardUserHeaderImage cardUserHeaderImage) {
        this.cardUserHeaderImage = cardUserHeaderImage;
    }

    public String getCardIdentifierJoinStr() {
        return cardIdentifierJoinStr;
    }

    public void setCardIdentifierJoinStr(String cardIdentifierJoinStr) {
        this.cardIdentifierJoinStr = cardIdentifierJoinStr;
    }

    public String getCardSerialNumberJoinStr() {
        return cardSerialNumberJoinStr;
    }

    public void setCardSerialNumberJoinStr(String cardSerialNumberJoinStr) {
        this.cardSerialNumberJoinStr = cardSerialNumberJoinStr;
    }

    public PhysicalCard getPhysicalCard() {
        return physicalCard;
    }

    public void setPhysicalCard(PhysicalCard physicalCard) {
        this.physicalCard = physicalCard;
    }
}
